require 'fileutils'
require 'c:/tools/kronos/ruby/line'
require 'c:/tools/kronos/ruby/state'
require 'c:/tools/kronos/ruby/merge'
require 'c:/tools/kronos/ruby/pseudostate'
require 'c:/tools/kronos/ruby/formalstate'

class FSMCode

	attr_accessor :interface
	attr_accessor :fsm

	def initialize( interface, fsm )

		@interface = interface
		@fsm = fsm
		# TODO: Verify Naming convention clarity
		@functionPrefix    = "#{@interface.namespace[0].capitalize}_#{@interface.package[0]}"
		@namePackageSmash  = "#{@interface.namespace[0].capitalize}#{@interface.package[0]}"

		@str1 				= String.new
		@str2 				= String.new
		@str3 				= String.new
		@string_buff	= String.new

		FileUtils.mkdir_p( "#{@interface.package[0].downcase}_fsm" )

		puts "Is this a Unit Test Build?"
		input = STDIN.gets

		if nil != input.index('y')
			@build_type = :UnitTest
		else
			@build_type = :FormalBuild
		end

		puts "Punch Machine?"
		input = STDIN.gets

		if nil != input.index('y')
			@fsm_type = :Punch
		else
			@fsm_type = :Traditional
		end

	end

	def createTablesFile

		Dir.chdir "./#{@interface.package[0].downcase}_fsm"

		tables = File.new( "#{@interface.package[0].downcase}_tables.c", "w+" )
		puts "Creating #{@interface.package[0].downcase}_tables.c"

		tables.write getHeader
		
		tables.write "/*-----------------------------------------------------------------------------\n"
		tables.write "* This file is meant to be included by #{@interface.package[0].downcase}_states.c\n"
		tables.write "*\n"
		tables.write "* DO NOT COMPILE DIRECTLY!!!\n"
		tables.write "*----------------------------------------------------------------------------*/\n\n"

		@fsm.formal_states.states.each { |key, state|

			tables.write "/*\n"
			tables.write " * STATE => #{key.upcase}\n"
			tables.write " */\n"

			tables.write "const "
			tables.write "#{@namePackageSmash}"
			tables.write "State_t "

			tables.write "_#{@namePackageSmash}"
			tables.write "State"
			tables.write "#{key} = "

			tables.write "{ #{@functionPrefix}Do_"
			tables.write "#{key}, {\n"

			@interface.events.each { |event|
				tables.write "  "
				tables.write "#{@functionPrefix}"
				tables.write "Event"
				tables.write "#{key}_"
				tables.write "#{event},\n"
			}

			tables.write "  "
			tables.write "}};\n\n"
		}

		tables.close

		Dir.chdir ".."

	end

	def createStatesFiles

		Dir.chdir "./#{@interface.package[0].downcase}_fsm"

		states = File.new( "#{@interface.package[0].downcase}_states.c", "w+" )
		puts "Creating #{@interface.package[0].downcase}_states.c"

		queueName = String.new "_#{@namePackageSmash}EventQueue"
		stateName = String.new "_#{@namePackageSmash}StateVar"

		states.write getHeader

		if @build_type == :UnitTest
			states.write "#ifdef DEBUG_#{@interface.package[0].upcase}\n"
			states.write "#include <stdio.h>\n"
			states.write "#endif\n\n"
		end

		states.write "#include \"#{@interface.package[0].downcase}_context.h\"\n"
		states.write "#include \"#{@interface.package[0].downcase}_fsmapi.h\"\n\n"
		
		@fsm.formal_states.states.each { |key, state_events|

			states.write "/*\n"
			states.write "*\n"
			states.write "* STATE => #{key.upcase}\n"
			states.write "*\n"
			states.write "*/\n"

			state_events.each{ |state_event|
				if nil != state_event.event_name
					event_exists = FALSE
					@interface.events.each{ |event|
						if state_event.event_name == event
							event_exists = TRUE
						end
					}

					if event_exists == FALSE
						puts "\nERROR: #{state_event.event_name} Event does not exist in FSM Interface. Please check.\n\n"
					end
				else
					event_exists = FALSE
					@interface.events.each{ |event|
						if event == state_event.actions[0] 
							event_exists = TRUE
						end
					}

					if event_exists == TRUE
						state_event.event_name = state_event.actions[0]
						state_event.actions.delete_at( 0 )
					else
						puts "\nERROR: Event is not properly marked. Search #{state_event.actions[0]} in FSM for ERROR destination\n\n"
					end
				end
			}

			@interface.events.each { |event|
				event_exists = FALSE
				state_events.each { |state_event|

					if event == state_event.event_name
						event_exists = TRUE
					end
				}
				if event_exists == FALSE
					@str1 << "#define #{@functionPrefix}Event#{key}_#{event}"
					@str2 << "0\n"
					states.write setStringSpacing( @str1, @str2, 80)
					
					@str1.clear
					@str2.clear
				end
			}

			states.write "\n"

			

			# Implement active event handlers
			@interface.events.each { |event|
				event_exists = FALSE
				state_events.each { |state_event|
					if event == state_event.event_name
						event_exists = TRUE
					end
				}

				# Write function name
				if event_exists == TRUE
					states.write "void "
					states.write "#{@functionPrefix}"
					states.write "Event"
					states.write "#{key}_"
					states.write "#{event}( void )\n{\n"

          state_events.each { |state_event|
						if event == state_event.event_name and nil != state_event.destination
							if state_event.destination != key
								states.write getIndention( 1 )
								states.write "#{@functionPrefix}"
								states.write "ChangeState_"
								states.write "#{state_event.destination.chomp}();\n"
							end
						end
          }

					# Write any initial actions on transition
					state_events.each { |state_event|
						if event == state_event.event_name and nil != state_event.actions
							state_event.actions.each { |action|
								action_found = FALSE
								@interface.actions.each{ | event |
									if event == action
										action_found = TRUE 
									end
								}
									
								if TRUE == action_found
									states.write getIndention( 1 )
									states.write "#{@functionPrefix}"
									states.write "#{action};\n"
								else
									puts "\nERROR: #{action} Action in Event #{state_event.event_name} does not exist in FSM Interface. Please check.\n\n"
								end
							}
						end
					}

					# Detect a transition or merge / decision to another state
					state_events.each { |state_event|
						# Merge / Decision string creation
						if event == state_event.event_name and nil != state_event.merge_statement
							states.write getMergeString( 1, state_event.merge_statement, key )
						end
					}

					states.write "}\n\n"
				end
			}

			states.write "\n\n"
		}


		states.write getBannerWithText( " ------------Including Construct State Tables------------" )

		@fsm.formal_states.states.each { |key, state|

			states.write "/*\n"
			states.write " * STATE => #{key.upcase}\n"
			states.write " */\n"

			states.write "const "
			states.write "#{@namePackageSmash}"
			states.write "State_t "

			states.write "_#{@namePackageSmash}"
			states.write "State"
			states.write "#{key} = "

			# Removing the DO Statement
			# states.write "{ #{@functionPrefix}Do_"
			# states.write "#{key}, {\n"
			states.write "{{\n"

			@interface.events.each { |event|
				states.write getIndention( 1 )
				states.write "#{@functionPrefix}"
				states.write "Event"
				states.write "#{key}_"
				states.write "#{event},\n"
			}

			states.write getIndention( 1 )
			# Removing the DO Statement
			# states.write "}};\n\n"
			states.write "}};\n\n"
		}

		# Used when construct tables were in seperate file. Consilidated for compiler ease.
		# states.write "#include \"#{@interface.package[0].downcase}_tables.c\""


		states.write getBannerWithText( " ------------FSM State Changes------------" )
		@fsm.formal_states.states.each { | key, state_events |
			states.write "void #{@functionPrefix}ChangeState_#{key}( void )\n"
			states.write "{\n"
			states.write getIndention( 1 )

			if @build_type == :UnitTest
				states.write "#ifdef DEBUG_#{@interface.package[0].upcase}\n"
				states.write "printf(\"#{@interface.package[0]}->Changing State: #{key}\\n\");\n"
				states.write "#endif\n\n"
			end

			states.write getIndention( 1 )
			states.write "_#{@namePackageSmash}StateVar = &_#{@namePackageSmash}State#{key};\n"
			states.write "}\n\n"
		}

		states.close

		states_header = File.new( "#{@interface.package[0].downcase}_states.h", "w+" )
		puts "Creating #{@interface.package[0].downcase}_states.h"

		states_header.write "#ifndef __#{@functionPrefix.downcase}_states_h_\n"
		states_header.write "#define __#{@functionPrefix.downcase}_states_h_\n"

		states_header.write getHeader

		states_header.write "/** Do not directly include this header file */\n"
		states_header.write "#if !defined(__#{@functionPrefix.downcase}_fsmapi_h_)\n"
		states_header.write "#error This is a private header file -- do not include directly.\n"
		states_header.write "#endif\n\n"

		states_header.write getBannerWithText " ------------Private Constants------------"
		states_header.write "#define #{@functionPrefix.upcase}FSM_NUM_EVENTS "
		states_header.write "#{@interface.events.length.to_s}\n\n"

		states_header.write getBannerWithText( " ------------FSM Typedefs------------")
		states_header.write "typedef void (*#{@namePackageSmash}EventAction_t)( void );\n"
		# Removing the DO Statement
		# states_header.write "typedef void (*#{@namePackageSmash}DoFunc_t)(void);\n\n"
		states_header.write "typedef struct\n"
		states_header.write "{\n"
		states_header.write getIndention( 1 )
		# TODO: Even all text spacing on fucntion declarations
		# Removing the DO Statement
		# states_header.write "#{@namePackageSmash}DoFunc_t             _do;\n"
		states_header.write getIndention( 1 )
		states_header.write "const #{@namePackageSmash}EventAction_t  "
		states_header.write "_eventActions[#{@functionPrefix.upcase}FSM_NUM_EVENTS];\n"
		states_header.write "} #{@namePackageSmash}State_t;\n"
		states_header.write "\n\n"

		states_header.write getBannerWithText( " ------------Private FSM Variables------------" )
		if @fsm_type == :Traditional
			states_header.write "/* Define event queue data type */\n"
			states_header.write "APL_STRUCTDEF_RBUF8(#{@functionPrefix}EventQueue_t, "
			states_header.write "OPTION_#{@functionPrefix.upcase}FSM_EVENTQUE_SIZE);\n\n"
			states_header.write "/* Allocate event queue */\n"
			states_header.write "struct #{@functionPrefix}EventQueue_t   #{queueName};\n\n"
		end
		states_header.write "/* FSM structure/handle */\n"
		states_header.write "const #{@namePackageSmash}State_t*        #{stateName};\n\n"
		states_header.write "\n\n"

		states_header.write getBannerWithText( " ------------Constants------------" )
		enum = 0

		@interface.events.each { | event |
	 		@str1 = "#define #{@functionPrefix.upcase}FSM_EV_#{event.upcase}"
			@str2 = "#{enum}\n"
			states_header.write setStringSpacing( @str1, @str2, 80 )

			@str1.clear
			@str2.clear
			enum = enum + 1
		}
		states_header.write "\n"

		states_header.write getBannerWithText( " ------------State Declarations------------" )

		@fsm.formal_states.states.each { | key, state_events |
			states_header.write "extern const #{@namePackageSmash}State_t _#{@namePackageSmash}State#{key};\n"
		}
		states_header.write "\n"

		states_header.write getBannerWithText( " ------------Method Declarations------------" )
		@fsm.formal_states.states.each { | key, state_events |
			states_header.write "void #{@functionPrefix}ChangeState_#{key}( void );\n"
		}

		# Used is just #define's for implementing states changes, moving to context state for easy debug
		# states_header.write getBannerWithText( " ------------Inlined Functions------------" )
		# @fsm.formal_states.states.each { | key, state_events |
			# @str1 = "#define #{@functionPrefix}ChangeState_#{key}()"
			# @str2 = "_#{@namePackageSmash}StateVar"
			# str_buff = setStringSpacing( @str1, @str2, 55 )
			# @str3 = "= &_#{@namePackageSmash}State#{key}\n"
			# states_header.write setStringSpacing( str_buff, @str3, (str_buff.length + 1) )

			# @str1.clear
			# @str2.clear
			# @str3.clear
			# str_buff.clear
		# }
		states_header.write "\n"

		states_header.write "#endif /* end __#{@functionPrefix.downcase}_states_h_ */"

		Dir.chdir ".."

	end


	def createFSMFile

		# Determine if i want to do a PunchMachine or our Traditional FSM
		# Create xx_fsm.c
		Dir.chdir "./#{@interface.package[0].downcase}_fsm"

		queueName = String.new "_#{@namePackageSmash}EventQueue"
		stateName = String.new "_#{@namePackageSmash}StateVar"

		fsm = File.new( "#{@interface.package[0].downcase}_fsm.c", "w+" )
		puts "Creating #{@interface.package[0].downcase}_fsm.c"
		
		fsm.write getHeader

		fsm.write "#include \"#{@interface.package[0].downcase}_fsmapi.h\"\n"
		fsm.write "#include \"#{@interface.package[0].downcase}_context.h\"\n\n"

		


		fsm.write getBannerWithText( " ------------FSM Implementation------------" )


		# Initialize the FSM
		fsm.write "void i#{@functionPrefix}FsmInitialize( void )\n"
		fsm.write "{\n\n"

		if @fsm_type == :Traditional
			fsm.write getIndention( 1 )
			fsm.write "Apl_rbuf8Initialize( &#{queueName}, "
			fsm.write "OPTION_#{@functionPrefix.upcase}FSM_EVENTQUE_SIZE);\n\n"
		end

		fsm.write getIndention( 1 )
		fsm.write "#{@functionPrefix}ConInitialize();\n"

		# Find Initial Transition
		@fsm.pseudo_states.each { |state|
			if "Initial Transition" == state.type
				if state.merge_statement == nil
					fsm.write getIndention( 1 )
					fsm.write "#{@functionPrefix}"
					fsm.write "ChangeState_"
					fsm.write "#{state.end_name.chomp}();\n\n"
				else
					# TODO: Fix Initial Transition if it contains a merge or decision
					fsm.write getMergeString( 1, state.merge_statement, "NONE" )
					fsm.write "\n"
				end
			end
		}
		fsm.write "}\n\n"

		if @fsm_type == :Traditional
			# Physical FSM Implementation
			fsm.write "void i#{@functionPrefix}FsmProcess( void )\n"
			fsm.write "{\n"

			# TODO: Even these guys up
			fsm.write getIndention( 1 )
			fsm.write "#{@namePackageSmash}EventAction_t    action;\n"
			fsm.write getIndention( 1 )
			fsm.write "Apl8u                  event;\n\n"

			fsm.write getIndention( 1 )
			fsm.write "while ( !Apl_rbuf8IsEmpty( &#{queueName} ) )\n"
			fsm.write getIndention( 1 )
			fsm.write "{\n"

			fsm.write getIndention( 2 )
			fsm.write "event = Apl_rbuf8Remove( &#{queueName} );\n\n"

			fsm.write getIndention( 2 )
			fsm.write "if ( (action = #{stateName}->_eventActions[event]) )\n"
			fsm.write getIndention( 2 )
			fsm.write "{\n"
			fsm.write getIndention( 3 )
			fsm.write "(*action)();\n"
			fsm.write getIndention( 2 )
			fsm.write "}\n"
			fsm.write getIndention( 1 )
			fsm.write "}\n"
			fsm.write "}\n\n"
		else
			fsm.write "void #{@functionPrefix}PunchMachine( AplBool punch )\n"
			fsm.write "{\n"
			fsm.write getIndention( 1 )
			fsm.write "#{@namePackageSmash}EventAction_t    action;\n\n"
			fsm.write getIndention( 1 )
			fsm.write "if ( (action = #{stateName}->_eventActions[punch]) )\n"
			fsm.write getIndention( 1 )
			fsm.write "{\n"
			fsm.write getIndention( 2 )
			fsm.write "(*action)();\n"
			fsm.write getIndention( 1 )
			fsm.write "}\n"
			fsm.write "}\n\n"
		end

		# FSM Events

		fsm.write getBannerWithText( " ------------FSM Event Registration------------" )

		@interface.events.each { |event|
			fsm.write "void i#{@functionPrefix}Event_#{event}( void )\n"
			fsm.write "{\n"

			fsm.write getIndention( 1 )
			if @fsm_type == :Traditional
				fsm.write "Apl_rbuf8Add(&#{queueName}, "
			else
				fsm.write "#{@functionPrefix}PunchMachine( "
			end
			fsm.write "#{@functionPrefix.upcase}FSM_EV_#{event.upcase} );\n"
			fsm.write "}\n\n"
		}

		# TODO: add do action statement

		fsm.close

		# Create xx_fsm.h
		fsm_header = File.new( "#{@interface.package[0].downcase}_fsm.h", "w+" )

		fsm_header.write "#ifndef __#{@functionPrefix.downcase}_fsm_h_\n"
		fsm_header.write "#define __#{@functionPrefix.downcase}_fsm_h_\n"

		fsm_header.write getHeader

		fsm_header.write "/** Do not directly include this header file */\n"
		fsm_header.write "#if !defined(__#{@functionPrefix.downcase}_fsmapi_h_)\n"
		fsm_header.write "#error This is a private header file -- do not include directly.\n"
		fsm_header.write "#endif\n\n"

		if@fsm_type == :Traditional
			fsm_header.write "#include \"apl/containers/ringbufapi.h\"\n"
		end
		fsm_header.write "#include \"#{@interface.package[0].downcase}_states.h\"\n\n"



		# FSM Functional Declarations
		fsm_header.write getBannerWithText( " ------------FSM Function Declarations------------")
		fsm_header.write "void i#{@functionPrefix}FsmInitialize( void );\n"
		if @fsm_type == :Traditional
			fsm_header.write "void i#{@functionPrefix}FsmProcess( void );"
		end
		fsm_header.write "\n\n"

		# FSM Event Declarations
		fsm_header.write getBannerWithText( " ------------FSM Event Functions------------")
		@interface.events.each { |event|
			fsm_header.write "void i#{@functionPrefix}Event_#{event}( void );\n"
		}
		fsm_header.write "\n\n"

		fsm_header.write "#endif /* end __#{@functionPrefix.downcase}_fsm_h_ */"

		fsm_header.close

		# Create xx.fsmapi.h
		fsm_api = File.new( "#{@interface.package[0].downcase}_fsmapi.h", "w+" )

		fsm_api.write "#ifndef __#{@functionPrefix.downcase}_fsmapi_h_\n"
		fsm_api.write "#define __#{@functionPrefix.downcase}_fsmapi_h_\n"
		fsm_api.write getHeader

		fsm_api.write "#include \"apl/types/types.h\"\n"
		fsm_api.write "#include \"#{@interface.namespace[0].downcase}cfg.h\"\n"
		fsm_api.write "#include \"platform/#{@namePackageSmash.downcase}.h\"\n\n"

		fsm_api.write getBannerWithText " ------------FSM Constants------------"

		if@fsm_type == :Traditional
			fsm_api.write "#ifndef OPTION_#{@functionPrefix.upcase}FSM_EVENTQUE_SIZE\n"
			fsm_api.write "#define OPTION_#{@functionPrefix.upcase}FSM_EVENTQUE_SIZE 20\n"
			fsm_api.write "#endif\n\n"
		end

		fsm_api.write getBannerWithText " ------------Inline Methods------------"
		fsm_api.write "#include \"vfunctions/#{@namePackageSmash.downcase}.h\"\n"
		fsm_api.write "#include \"#{@interface.package[0].downcase}_fsm.h\"\n\n"

		fsm_api.write getBannerWithText " ------------Public/Published API Methods------------"

		fsm_api.write "/* This method initialize the FSM interface\n"
		fsm_api.write "\n"
		fsm_api.write "     Prototype:\n"
		fsm_api.write "               void #{@functionPrefix}FsmInitialize( void )\n"
		fsm_api.write "*/\n"
		str1 = "#define #{@functionPrefix}FsmInitialize"
		str2 = "i#{@functionPrefix}FsmInitialize\n\n"
		fsm_api.write setStringSpacing( str1, str2, 55 )

		str1.clear
		str2.clear

		if @fsm_type == :Traditional
			fsm_api.write "/* This method executes the FSM on a periodic basis. This method\n"
			fsm_api.write "   should be called from the 'Main Loop'\n"
			fsm_api.write "\n"
			fsm_api.write "     Prototype:\n"
			fsm_api.write "               void #{@functionPrefix}FsmProcess( void )\n"
			fsm_api.write "*/\n"
			str1 = "#define #{@functionPrefix}FsmProcess"
			str2 = "i#{@functionPrefix}FsmProcess\n\n"
			fsm_api.write setStringSpacing( str1, str2, 55 )

			str1.clear
			str2.clear
		end

		fsm_api.write "/* The following methods generate the events to be process by the FSM\n"
		fsm_api.write "\n"
		fsm_api.write "     Prototype:\n"
		fsm_api.write "               void #{@functionPrefix}Event_xxx( void )\n"
		fsm_api.write "*/\n\n"
		@interface.events.each { |event|
			str1 = "#define #{@functionPrefix}Event_#{event}"
			str2 = "i#{@functionPrefix}Event_#{event}\n"
			fsm_api.write setStringSpacing( str1, str2, 55 )

			str1.clear
			str2.clear
		}

		fsm_api.write "\n"

		fsm_api.write "#endif /* end __#{@functionPrefix.downcase}_fsm_h_ */"

		Dir.chdir ".."

	end

	def createContextFiles

		# Creating xx_context.c file
		Dir.chdir "./#{@interface.package[0].downcase}_fsm"

		context = File.new( "#{@interface.package[0].downcase}_context.c", "w+" )
		puts "Creating #{@interface.package[0].downcase}_context.c"

		context.write getHeader

		if @build_type == :UnitTest
			context.write "#ifdef DEBUG_#{@interface.package[0].upcase}\n"
			context.write "#include <stdio.h>\n"
			context.write "#endif\n\n"
		end

		context.write "#include \"apl/types/types.h\"\n"
		context.write "#include \"#{@interface.namespace[0].downcase}cfg.h\"\n"
		context.write "#include \"#{@interface.package[0].downcase}_context.h\"\n"
		context.write "#include \"#{@interface.package[0].downcase}_fsmapi.h\"\n\n"


		context.write getBannerWithText " ------------Initialization Methods------------"

		context.write "void #{@functionPrefix}ConInitialize( void )\n"
		context.write "{\n"
		context.write getIndention( 1 )
		context.write "/* TODO: I want something to do!!!*/\n"
		context.write "}\n\n"

		context.write getBannerWithText " ------------Actions------------"

		@interface.actions.each { |action|
			str_buff = action.clone

			start_strip = str_buff.index "("
			stop_strip  = str_buff.index ")"
			str_buff.slice!(start_strip..stop_strip)

			context.write "void #{@functionPrefix}#{str_buff}( void )\n"
			context.write "{\n"
			context.write getIndention( 1 )
			context.write "/* TODO: I want something to do!!!*/\n"

			if @build_type == :UnitTest
				context.write "#ifdef DEBUG_#{@interface.package[0].upcase}\n"
				context.write getIndention( 1 )
				context.write "printf(\"#{@interface.package[0]}->Action: #{@functionPrefix}#{str_buff}\\n\");\n"
				context.write "#endif\n\n"
			end

			context.write "}\n\n"
		}

		context.write getBannerWithText " ------------Guards------------"

		if( nil != @interface.guards )
			@interface.guards.each { |guard|
				str_buff = guard.clone

				start_strip = str_buff.index "("
				stop_strip  = str_buff.index ")"
				str_buff.slice!(start_strip..stop_strip)

				context.write "AplBool #{@functionPrefix}#{str_buff}( void )\n"
				context.write "{\n"
				context.write getIndention( 1 )
				context.write "/* TODO: I want something to do!!!*/\n"
				context.write getIndention( 1 )
				context.write "AplBool guard = 0;\n"
				context.write "#ifdef DEBUG_#{@interface.package[0].upcase}\n"
				context.write getIndention( 1 )
				context.write "printf(\"#{@interface.package[0]}->Guard: Checking #{str_buff}: %d\\n\", guard);\n"
				context.write "#endif\n\n"
				context.write getIndention( 1 )
				context.write "return guard;\n"
				context.write "}\n\n"
			}
		end

		context.close

		# Creating xx_context.h file
		context = File.new( "#{@interface.package[0].downcase}_context.h", "w+" )
		puts "Creating #{@interface.package[0].downcase}_context.h"

		context.write getHeader

		context.write "#include \"apl/types/types.h\"\n"
		context.write "#include \"#{@interface.namespace[0].downcase}cfg.h\"\n\n"

		context.write getBannerWithText " ------------FSM Initialization Methods------------"

		context.write "void #{@functionPrefix}ConInitialize( void );\n\n"

		context.write getBannerWithText " ------------FSM Actions------------"

		@interface.actions.each { |action|
			str_buff = action.clone

			start_strip = str_buff.index "("
			stop_strip  = str_buff.index ")"
			str_buff.slice!(start_strip..stop_strip)

			context.write "void #{@functionPrefix}#{str_buff}( void );\n"
		}

		context.write "\n\n"

		context.write getBannerWithText " ------------FSM Guards------------"

		if( nil != @interface.guards )
			@interface.guards.each { |guard|
				str_buff = guard.clone

				start_strip = str_buff.index "("
				stop_strip  = str_buff.index ")"
				str_buff.slice!(start_strip..stop_strip)

				context.write "AplBool #{@functionPrefix}#{str_buff}( void );\n"
			}
		end

		context.close


		Dir.chdir ".."

	end

	def getMergeString( indent, merge_statement, current_state )

		str_buff = String.new
		str_comp = String.new

		# Detect merge only
		# BUG: Merge not detected when line ends into a decision or merge statement
		if ( nil != merge_statement[:destination] ) or 
			 ( nil == merge_statement[:else_guard] and 
			   nil == merge_statement[:guard] ) 

      if FALSE == merge_statement[:recurse]
				if merge_statement[:destination] != current_state
					str_buff << getIndention( indent )
					str_buff << "#{@functionPrefix}"
					str_buff << "ChangeState_"
					str_buff << "#{merge_statement[:destination]}();\n"
				end
      end

			if nil != merge_statement[:actions]
				merge_statement[:actions].each { | action |
					str_buff << getIndention( indent )
					str_buff << "#{@functionPrefix}"
					str_buff << "#{action};\n"
				}
			end

			if FALSE != merge_statement[:recurse]
				# recursive call in case another merge or decision is met 
				# TODO: Check to see if we are looking for TRUE == merge_statement[:recurse]
				# I think this was a bug
				str_buff << getMergeString( indent, merge_statement[:branch], current_state )
			end

		else

			# Detect a decision 
			if nil != merge_statement[:guard]

				str_buff << getIndention( indent )
				str_buff << "if( #{@functionPrefix}#{merge_statement[:guard]} )\n"

				str_buff << getIndention( indent )
				str_buff << "{\n"

				str_comp = str_buff.clone

        if FALSE == merge_statement[:guard_recurse]
					if merge_statement[:guard_destination] != current_state
						str_buff << getIndention( indent + 1 )
						str_buff << "#{@functionPrefix}"
						str_buff << "ChangeState_"
						str_buff << "#{merge_statement[:guard_destination].chomp}();\n"
					end
        end

				if nil != merge_statement[:guard_actions]
					merge_statement[:guard_actions].each { |action|
						str_buff << getIndention( indent + 1 )
						str_buff << "#{@functionPrefix}"
						str_buff << "#{action};\n"
					}
				end

				if FALSE != merge_statement[:guard_recurse]
					str_buff << getMergeString( indent + 1, merge_statement[:guard_branch], current_state )
				end

				if str_comp == str_buff
					str_buff << getIndention( indent + 1 )
					str_buff << "/* Do Nothing */\n" 
				end

				str_buff << getIndention( indent )
				str_buff << "}\n"

				str_buff << getIndention( indent )
				str_buff << "else\n"
				str_buff << getIndention( indent )
				str_buff << "{\n"

				str_comp = str_buff.clone

        if FALSE == merge_statement[:else_recurse]
					if nil != merge_statement[:else_destination]
						if merge_statement[:else_destination] != current_state
							str_buff << getIndention( indent + 1 )
							str_buff << "#{@functionPrefix}"
							str_buff << "ChangeState_"
							str_buff << "#{merge_statement[:else_destination].chomp}();\n"
						end
					end
        end

				if nil != merge_statement[:else_actions]
					merge_statement[:else_actions].each { |action|
						str_buff << getIndention( indent + 1 )
					str_buff << "#{@functionPrefix}"
						str_buff << "#{action};\n"
					}
				end

				if FALSE != merge_statement[:else_recurse]
					str_buff << getMergeString( indent + 1, merge_statement[:else_branch], current_state )
				end

				if str_comp == str_buff
					str_buff << getIndention( indent + 1 )
					str_buff << "/* Do Nothing */\n" 
				end

				str_buff << getIndention( indent )
				str_buff << "}\n"

			end

		end

		return str_buff

	end

	def getBannerWithText( banner_text )

		# TODO: Make this a print multiple lines fo banner text
		# (not just a single line that must not contain that many characters

		str_buff = String.new

		str_buff << "/**#{banner_text}\n"
		str_buff << " */\n\n"

		return str_buff

	end

	def getHeader

		str_buff = String.new
		time = Time.new

		str_buff << "/*-----------------------------------------------------------------------------\n"
		str_buff << "* This Information is proprietary to Trane Incorporated, Tyler, Texas and MAY NOT\n"
		str_buff << "* be copied by any method or incorporated into another program without the\n"
		str_buff << "* express written consent of Trane Incorporated. This Information or any portion\n"
		str_buff << "* thereof remains the property of Trane Incorporated. The Information contained herein\n"
		str_buff << "* is believed to be accurate and Trane Incorporated assumes no responsibility or\n"
		str_buff << "* liability for its use in any way and conveys no license or title under any\n"
		str_buff << "* patent or copyright and makes no representation or warranty that this\n"
		str_buff << "* Information is free from patent or copyright infringement.\n"
		str_buff << "*\n"
		str_buff << "* Copyright (c) #{time.year} Trane Incorporated. ALL RIGHTS RESERVED.\n"
		str_buff << "*----------------------------------------------------------------------------*/\n\n"

		str_buff << "/*-----------------------------------------------------------------------------\n"
		str_buff << "*   Namespace: #{@interface.namespace[0].upcase}\n"
		str_buff << "*   Package  : #{@interface.package[0].upcase}\n"
		str_buff << "*   Interface: #{@interface.interface[0].upcase}\n"
		str_buff << "*----------------------------------------------------------------------------*/\n\n"

		return str_buff

	end

	def getIndention( indent_number )

		str_buff = String.new
		
		indent_number.times {
			str_buff << "  "
		}

		return str_buff

	end

	def setStringSpacing( s1, s2, offset )

		blank_spaces = offset - s1.length
		out_str = s1.clone

		out_str << " "

		blank_spaces.times {
			out_str << " "
		}

		if 0 == blank_spaces
			out_str << " "
		end

		out_str << s2

		return out_str

	end

end
